using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using WegasManagementSystem.DAL;
using WegasManagementSystem.Models;
using WegasManagementSystem.Utils;
using System.IO;

namespace WegasManagementSystem.BLL
{
    /// <summary>
    /// 考勤业务逻辑类
    /// </summary>
    public class AttendanceBLL
    {
        private readonly AttendanceDAL _attendanceDAL;
        private readonly EmployeeDAL _employeeDAL;
        private readonly DepartmentDAL _departmentDAL;

        /// <summary>
        /// 构造函数
        /// </summary>
        public AttendanceBLL()
        {
            _attendanceDAL = new AttendanceDAL();
            _employeeDAL = new EmployeeDAL();
            _departmentDAL = new DepartmentDAL();
        }

        /// <summary>
        /// 添加考勤记录
        /// </summary>
        /// <param name="attendance">考勤对象</param>
        /// <returns>新考勤ID，失败返回0</returns>
        public int AddAttendance(AttendanceInfo attendance)
        {
            if (attendance == null)
                throw new ArgumentNullException(nameof(attendance), "考勤信息不能为空");

            if (attendance.EmpId <= 0)
                throw new ArgumentException("员工ID无效", nameof(attendance.EmpId));

            if (attendance.DeptId <= 0)
                throw new ArgumentException("部门ID无效", nameof(attendance.DeptId));

            if (attendance.Year <= 0 || attendance.Month <= 0 || attendance.Month > 12)
                throw new ArgumentException("年份或月份无效");

            // 检查员工是否存在
            var employee = _employeeDAL.GetEmployeeById(attendance.EmpId);
            if (employee == null)
                throw new InvalidOperationException($"员工ID {attendance.EmpId} 不存在");

            // 检查部门是否存在
            var department = _departmentDAL.GetDepartmentById(attendance.DeptId);
            if (department == null)
                throw new InvalidOperationException($"部门ID {attendance.DeptId} 不存在");

            // 检查是否已存在该员工该月的考勤记录
            var existingAttendance = _attendanceDAL.GetAttendanceByEmployee(attendance.EmpId, attendance.Year, attendance.Month);
            if (existingAttendance != null)
                throw new InvalidOperationException($"员工 {employee.Name} 在 {attendance.Year}年{attendance.Month}月 的考勤记录已存在");

            // 添加考勤记录
            return _attendanceDAL.AddAttendance(attendance);
        }

        /// <summary>
        /// 更新考勤记录
        /// </summary>
        /// <param name="attendance">考勤对象</param>
        /// <returns>更新成功返回true，失败返回false</returns>
        public bool UpdateAttendance(AttendanceInfo attendance)
        {
            if (attendance == null)
                throw new ArgumentNullException(nameof(attendance), "考勤信息不能为空");

            if (attendance.AttendanceId <= 0)
                throw new ArgumentException("考勤ID无效", nameof(attendance.AttendanceId));

            if (attendance.EmpId <= 0)
                throw new ArgumentException("员工ID无效", nameof(attendance.EmpId));

            if (attendance.DeptId <= 0)
                throw new ArgumentException("部门ID无效", nameof(attendance.DeptId));

            if (attendance.Year <= 0 || attendance.Month <= 0 || attendance.Month > 12)
                throw new ArgumentException("年份或月份无效");

            // 检查考勤记录是否存在
            var existingAttendance = _attendanceDAL.GetAttendanceById(attendance.AttendanceId);
            if (existingAttendance == null)
                throw new InvalidOperationException($"考勤ID {attendance.AttendanceId} 不存在");

            // 检查员工是否存在
            var employee = _employeeDAL.GetEmployeeById(attendance.EmpId);
            if (employee == null)
                throw new InvalidOperationException($"员工ID {attendance.EmpId} 不存在");

            // 检查部门是否存在
            var department = _departmentDAL.GetDepartmentById(attendance.DeptId);
            if (department == null)
                throw new InvalidOperationException($"部门ID {attendance.DeptId} 不存在");

            // 更新考勤记录
            attendance.UpdatedTime = DateTime.Now;
            return _attendanceDAL.UpdateAttendance(attendance);
        }

        /// <summary>
        /// 删除考勤记录
        /// </summary>
        /// <param name="attendanceId">考勤ID</param>
        /// <returns>删除成功返回true，失败返回false</returns>
        public bool DeleteAttendance(int attendanceId)
        {
            if (attendanceId <= 0)
                throw new ArgumentException("考勤ID无效", nameof(attendanceId));

            // 检查考勤记录是否存在
            var attendance = _attendanceDAL.GetAttendanceById(attendanceId);
            if (attendance == null)
                throw new InvalidOperationException($"考勤ID {attendanceId} 不存在");

            // 删除考勤记录
            return _attendanceDAL.DeleteAttendance(attendanceId);
        }

        /// <summary>
        /// 获取员工某月的考勤记录
        /// </summary>
        /// <param name="empId">员工ID</param>
        /// <param name="year">年份</param>
        /// <param name="month">月份</param>
        /// <returns>考勤对象</returns>
        public AttendanceInfo GetAttendanceByEmployee(int empId, int year, int month)
        {
            if (empId <= 0)
                throw new ArgumentException("员工ID无效", nameof(empId));

            if (year <= 0 || month <= 0 || month > 12)
                throw new ArgumentException("年份或月份无效");

            return _attendanceDAL.GetAttendanceByEmployee(empId, year, month);
        }

        /// <summary>
        /// 获取部门某月的考勤记录
        /// </summary>
        /// <param name="deptId">部门ID</param>
        /// <param name="year">年份</param>
        /// <param name="month">月份</param>
        /// <returns>考勤记录列表</returns>
        public List<AttendanceInfo> GetAttendancesByDepartment(int deptId, int year, int month)
        {
            return GetAttendanceByDepartment(deptId, year, month);
        }

        /// <summary>
        /// 获取部门某月的考勤记录
        /// </summary>
        /// <param name="deptId">部门ID</param>
        /// <param name="year">年份</param>
        /// <param name="month">月份</param>
        /// <returns>考勤对象列表</returns>
        public List<AttendanceInfo> GetAttendanceByDepartment(int deptId, int year, int month)
        {
            if (deptId < 0) // 0表示所有部门
                throw new ArgumentException("部门ID无效", nameof(deptId));

            if (year <= 0 || month <= 0 || month > 12)
                throw new ArgumentException("年份或月份无效");

            // 获取所有部门的考勤记录
            if (deptId == 0)
                return GetAllAttendancesByYearMonth(year, month);

            return _attendanceDAL.GetAttendanceByDepartment(deptId, year, month);
        }

        /// <summary>
        /// 获取所有考勤记录
        /// </summary>
        /// <returns>考勤记录列表</returns>
        public List<AttendanceInfo> GetAllAttendances()
        {
            return _attendanceDAL.GetAllAttendances();
        }

        /// <summary>
        /// 获取指定年月的所有考勤记录
        /// </summary>
        /// <param name="year">年份</param>
        /// <param name="month">月份</param>
        /// <returns>考勤记录列表</returns>
        public List<AttendanceInfo> GetAllAttendancesByYearMonth(int year, int month)
        {
            if (year <= 0 || month <= 0 || month > 12)
                throw new ArgumentException("年份或月份无效");

            // 获取所有考勤记录
            var allAttendances = _attendanceDAL.GetAllAttendances();
            
            // 筛选指定年月的记录
            return allAttendances.Where(a => a.Year == year && a.Month == month).ToList();
        }

        /// <summary>
        /// 批量添加考勤记录
        /// </summary>
        /// <param name="attendanceList">考勤对象列表</param>
        /// <returns>成功添加的记录数</returns>
        public int BatchAddAttendance(List<AttendanceInfo> attendanceList)
        {
            if (attendanceList == null || attendanceList.Count == 0)
                throw new ArgumentException("考勤列表不能为空", nameof(attendanceList));

            // 验证所有考勤记录
            foreach (var attendance in attendanceList)
            {
                if (attendance.EmpId <= 0)
                    throw new ArgumentException($"员工ID {attendance.EmpId} 无效");

                if (attendance.DeptId <= 0)
                    throw new ArgumentException($"部门ID {attendance.DeptId} 无效");

                if (attendance.Year <= 0 || attendance.Month <= 0 || attendance.Month > 12)
                    throw new ArgumentException($"年份 {attendance.Year} 或月份 {attendance.Month} 无效");

                // 设置创建和更新时间
                attendance.CreatedTime = DateTime.Now;
                attendance.UpdatedTime = DateTime.Now;
            }

            return _attendanceDAL.BatchAddAttendance(attendanceList);
        }

        /// <summary>
        /// 从Excel导入考勤记录
        /// </summary>
        /// <param name="filePath">Excel文件路径</param>
        /// <returns>成功导入的记录数</returns>
        public int ImportAttendanceFromExcel(string filePath)
        {
            if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath))
                throw new ArgumentException("文件路径无效或文件不存在", nameof(filePath));

            // 从Excel读取数据到DataTable
            DataTable dt = ExcelHelper.ImportFromExcel(filePath);
            if (dt == null || dt.Rows.Count == 0)
                return 0;

            List<AttendanceInfo> attendanceList = new List<AttendanceInfo>();

            // 遍历数据行，转换为考勤对象
            foreach (DataRow row in dt.Rows)
            {
                try
                {
                    // 检查必要列是否存在
                    if (!dt.Columns.Contains("工号") || !dt.Columns.Contains("姓名") || 
                        !dt.Columns.Contains("年份") || !dt.Columns.Contains("月份") ||
                        !dt.Columns.Contains("应出勤天数") || !dt.Columns.Contains("实际出勤天数"))
                        throw new Exception("Excel文件格式不正确，缺少必要的列");

                    // 获取员工信息
                    string empNumber = row["工号"].ToString();
                    Employee employee = _employeeDAL.GetEmployeeByNumber(empNumber);
                    if (employee == null)
                        throw new Exception($"员工号为 {empNumber} 的员工不存在");

                    // 获取年月
                    int year, month;
                    if (!int.TryParse(row["年份"].ToString(), out year) || year <= 0)
                        throw new Exception($"年份格式不正确: {row["年份"]}");
                    if (!int.TryParse(row["月份"].ToString(), out month) || month <= 0 || month > 12)
                        throw new Exception($"月份格式不正确: {row["月份"]}");

                    // 创建考勤对象
                    AttendanceInfo attendance = new AttendanceInfo
                    {
                        EmpId = employee.EmpId,
                        DeptId = employee.DeptId,
                        Year = year,
                        Month = month,
                        CreatedTime = DateTime.Now,
                        UpdatedTime = DateTime.Now
                    };

                    // 设置考勤数据
                    decimal workDays;
                    if (decimal.TryParse(row["应出勤天数"].ToString(), out workDays))
                        attendance.WorkDays = workDays;
                    else
                        attendance.WorkDays = 21.75M; // 默认值

                    decimal actualWorkDays;
                    if (decimal.TryParse(row["实际出勤天数"].ToString(), out actualWorkDays))
                        attendance.ActualWorkDays = actualWorkDays;
                    else
                        attendance.ActualWorkDays = 0;

                    decimal absenceDays;
                    if (dt.Columns.Contains("缺勤天数") && decimal.TryParse(row["缺勤天数"].ToString(), out absenceDays))
                        attendance.AbsenceDays = absenceDays;
                    else
                        attendance.AbsenceDays = attendance.WorkDays - attendance.ActualWorkDays;

                    decimal overtimeHours;
                    if (dt.Columns.Contains("加班小时数") && decimal.TryParse(row["加班小时数"].ToString(), out overtimeHours))
                        attendance.OvertimeHours = overtimeHours;
                    else
                        attendance.OvertimeHours = 0;

                    int lateCount;
                    if (dt.Columns.Contains("迟到次数") && int.TryParse(row["迟到次数"].ToString(), out lateCount))
                        attendance.LateCount = lateCount;
                    else
                        attendance.LateCount = 0;

                    int earlyLeaveCount;
                    if (dt.Columns.Contains("早退次数") && int.TryParse(row["早退次数"].ToString(), out earlyLeaveCount))
                        attendance.EarlyLeaveCount = earlyLeaveCount;
                    else
                        attendance.EarlyLeaveCount = 0;

                    // 检查是否已存在该员工该月的考勤记录
                    var existingAttendance = _attendanceDAL.GetAttendanceByEmployee(attendance.EmpId, attendance.Year, attendance.Month);
                    if (existingAttendance != null)
                        throw new Exception($"员工 {employee.Name} 在 {attendance.Year}年{attendance.Month}月 的考勤记录已存在");

                    attendanceList.Add(attendance);
                }
                catch (Exception)
                {
                    // 忽略此行出现的错误，继续处理下一行
                    continue;
                }
            }

            // 批量添加考勤记录
            return _attendanceDAL.BatchAddAttendance(attendanceList);
        }

        /// <summary>
        /// 导出考勤记录到Excel
        /// </summary>
        /// <param name="deptId">部门ID，为0表示导出所有部门</param>
        /// <param name="year">年份</param>
        /// <param name="month">月份</param>
        /// <param name="filePath">导出文件路径</param>
        /// <returns>是否导出成功</returns>
        public bool ExportAttendanceToExcel(int deptId, int year, int month, string filePath)
        {
            if (string.IsNullOrEmpty(filePath))
                throw new ArgumentException("文件路径不能为空", nameof(filePath));

            if (year <= 0 || month <= 0 || month > 12)
                throw new ArgumentException("年份或月份无效");

            // 获取考勤记录
            List<AttendanceInfo> attendanceList;
            if (deptId > 0)
                attendanceList = _attendanceDAL.GetAttendanceByDepartment(deptId, year, month);
            else
                attendanceList = GetAllAttendancesByYearMonth(year, month);

            if (attendanceList == null || attendanceList.Count == 0)
                return false;

            // 创建DataTable
            DataTable dt = new DataTable("考勤记录");
            dt.Columns.Add("工号", typeof(string));
            dt.Columns.Add("姓名", typeof(string));
            dt.Columns.Add("部门", typeof(string));
            dt.Columns.Add("年份", typeof(int));
            dt.Columns.Add("月份", typeof(int));
            dt.Columns.Add("应出勤天数", typeof(decimal));
            dt.Columns.Add("实际出勤天数", typeof(decimal));
            dt.Columns.Add("缺勤天数", typeof(decimal));
            dt.Columns.Add("加班小时数", typeof(decimal));
            dt.Columns.Add("迟到次数", typeof(int));
            dt.Columns.Add("早退次数", typeof(int));

            // 填充数据
            foreach (var attendance in attendanceList)
            {
                var employee = _employeeDAL.GetEmployeeById(attendance.EmpId);
                if (employee == null)
                    continue;

                DataRow row = dt.NewRow();
                row["工号"] = employee.EmpNumber;
                row["姓名"] = attendance.EmpName ?? employee.Name;
                row["部门"] = attendance.DeptName ?? _departmentDAL.GetDepartmentById(attendance.DeptId)?.DeptName;
                row["年份"] = attendance.Year;
                row["月份"] = attendance.Month;
                row["应出勤天数"] = attendance.WorkDays;
                row["实际出勤天数"] = attendance.ActualWorkDays;
                row["缺勤天数"] = attendance.AbsenceDays;
                row["加班小时数"] = attendance.OvertimeHours;
                row["迟到次数"] = attendance.LateCount;
                row["早退次数"] = attendance.EarlyLeaveCount;
                dt.Rows.Add(row);
            }

            // 导出到Excel文件
            return ExcelHelper.ExportToExcel(dt, filePath);
        }
    }
} 